﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

using CtpApi;
using CtpApi.Struct;

namespace CtpTest
{
    class Program
    {
        static void Main(string[] args)
        {
            TdClass ac = new TdClass();
            Task task = Task.Factory.StartNew(ac.Run);
            task.Wait();
        }
    }
    
    class TdClass
    {
        CtpTdApi tdApi;

        int requestID = 0;

        CThostFtdcDepthMarketDataField marketData;

        string BROKERID = "4030";
        string USERID   = "80002863";
        string PASSWORD = "888888";

        /// <summary>
        /// 发生错误显示错误信息
        /// </summary>
        /// <param name="pRspInfo">响应信息</param>
        private void DebugAction(string eventName, CThostFtdcRspInfoField pRspInfo = null)
        {
            System.Console.WriteLine("");
            System.Console.WriteLine(eventName);

            if (pRspInfo != null && pRspInfo.ErrorID != 0)
            {
                System.Console.WriteLine(pRspInfo.ErrorMsg);
                //while(true);
            }
        }

        /// <summary>
        /// 显示指定结构的内容
        /// </summary>
        /// <param name="field">结构</param>
        private void DisplayFieldInfo(object field)
        {
            if (field != null)
            {
                Type fieldType = field.GetType();

                foreach (PropertyInfo pInfo in fieldType.GetProperties())
                {
                    Console.WriteLine(pInfo.Name + "=" + pInfo.GetValue(field, null));
                }
            }
        }


        private void UserFun(CThostFtdcRspUserLoginField rspUserLoginfield)
        {
            //this.QrySettlementConfirmInfo();

            //this.InsertOrder();
            this.QryInvestorPosition("");
        }


        /// <summary>
        /// 查询账单
        /// </summary>
        private void QryOrder()
        {
            CThostFtdcQryOrderField field = new CThostFtdcQryOrderField();

            //field.
        }

        /// <summary>
        /// 请求查询投资者
        /// </summary>
        private void QryInvestor()
        {
            CThostFtdcQryInvestorField field = new CThostFtdcQryInvestorField();

            field.BrokerID = BROKERID;
            field.InvestorID = USERID;

            tdApi.ReqQryInvestor(field, requestID++);
        }


        /// <summary>
        /// 请求查询投资者持仓
        /// </summary>
        private void QryInvestorPosition(string instrumentID)
        { 
            CThostFtdcQryInvestorPositionField field = new CThostFtdcQryInvestorPositionField();

            field.BrokerID = BROKERID;
            field.InvestorID = USERID;
            field.InstrumentID = instrumentID;

            tdApi.ReqQryInvestorPosition(field, requestID++);
        }

        /// <summary>
        /// 请求查询投资者持仓明细
        /// </summary>
        private void QryInvestorPositionDetail(string instrumentID)
        {
            CThostFtdcQryInvestorPositionDetailField field = new CThostFtdcQryInvestorPositionDetailField();

            field.BrokerID = BROKERID;
            field.InvestorID = USERID;
            field.InstrumentID = instrumentID;

            tdApi.ReqQryInvestorPositionDetail(field, requestID++);
        }

        /// <summary>
        /// 请求查询投资者组合持仓明细
        /// </summary>
        private void QryInvestorPositionCombineDetail(string combInstrumentID)
        {
            CThostFtdcQryInvestorPositionCombineDetailField field = new CThostFtdcQryInvestorPositionCombineDetailField();

            field.BrokerID = BROKERID;
            field.InvestorID = USERID;
            field.CombInstrumentID = combInstrumentID;

            tdApi.ReqQryInvestorPositionCombineDetail(field, requestID++);
        }


        /// <summary>
        /// 查询合约信息
        /// </summary>
        /// <param name="instrumentID"></param>
        private void QryInstrument(string instrumentID)
        {
            CThostFtdcQryInstrumentField instrument = new CThostFtdcQryInstrumentField();

            instrument.InstrumentID = instrumentID;
            tdApi.ReqQryInstrument(instrument, requestID++);
        }

        /// <summary>
        /// 查询指定合约行情
        /// </summary>
        /// <param name="instrumentID">合约代码</param>
        private void QryDepthMarketData(string instrumentID)
        {
            CThostFtdcQryDepthMarketDataField field = new CThostFtdcQryDepthMarketDataField();

            field.InstrumentID = instrumentID;

            tdApi.ReqQryDepthMarketData(field, requestID++);
        }


        /// <summary>
        /// 查询投资者结算确认结果
        /// </summary>
        private void QrySettlementConfirmInfo()
        {
            CThostFtdcQrySettlementInfoConfirmField field = new CThostFtdcQrySettlementInfoConfirmField();

            field.BrokerID = BROKERID;
            field.InvestorID = USERID;

            tdApi.ReqQrySettlementInfoConfirm(field, requestID++);
        }

        /// <summary>
        /// 确认投资者结算
        /// </summary>
        private void ReqSettlementConfirmInfo()
        {
            CThostFtdcSettlementInfoConfirmField field = new CThostFtdcSettlementInfoConfirmField();

            field.BrokerID = BROKERID;
            field.InvestorID = USERID;
            field.ConfirmDate = DateTime.Now.ToString("yyyyMMdd");
            field.ConfirmTime = DateTime.Now.ToString("HH:mm:ss");

            tdApi.ReqSettlementInfoConfirm(field, requestID++);
        }

        /// <summary>
        /// 查询投资者结算信息
        /// </summary>
        private void QrySettlementInfo()
        {
            CThostFtdcQrySettlementInfoField field = new CThostFtdcQrySettlementInfoField();

            field.BrokerID = BROKERID;
            field.InvestorID = USERID;
            //field.TradingDay = DateTime.Now.ToString("yyyyMMdd");不填日期表示取上一次交易结算单

            tdApi.ReqQrySettlementInfo(field, requestID++);
        }


        /// <summary>
        /// 报单录入
        /// </summary>
        private void InsertOrder()
        {
            //this.QryDepthMarketData("ru1205");

            CThostFtdcInputOrderField order = new CThostFtdcInputOrderField();

            order.BrokerID     = BROKERID;
            order.UserID       = USERID;
            order.InvestorID   = USERID;
            
            order.InstrumentID = "ru1205";

            order.LimitPrice = 28700;
            order.StopPrice  = 0;
            order.VolumeTotalOriginal = 2;
            order.Direction = DirectionEnum.Sell;

            order.MinVolume = 1;
            order.TimeCondition = TimeConditionEnum.IOC;
            order.OrderPriceType = OrderPriceTypeEnum.LimitPrice;
            order.VolumeCondition = VolumeConditionEnum.AV;
            order.ContingentCondition = ContingentConditionEnum.Immediately;

            order.OrderRef = "1";
            order.RequestID = requestID++;

            order.GTDDate = "";
            order.TimeCondition = TimeConditionEnum.GFD;
            
            order.IsAutoSuspend = 0;
            order.UserForceClose = 0;
            order.ForceCloseReason = ForceCloseReasonEnum.NotForceClose;

            order.CombHedgeFlag = MyHedgeFlag.Speculation;
            order.CombOffsetFlag = MyOffsetFlag.CloseToday;

            tdApi.ReqOrderInsert(order, requestID++);
        }

        /********************************** Event **********************************/


        public void Run()
        {
            //string frontAddresses = "tcp://61.144.241.113:41213";
            string frontAddresses = @"tcp://asp-sim2-front1.financial-trading-platform.com:26205";

            tdApi = new CtpTdApi();
            tdApi.RegisterFront(frontAddresses);

            tdApi.CtpTdEvents.OnRspError += this.OnRspError;                            //错误应答

            tdApi.CtpTdEvents.OnFrontConnected += this.OnFrontConnected;                //连接请求响应
            tdApi.CtpTdEvents.OnRspUserLogin   += this.OnRspUserLogin;                  //用户登录请求响应

            tdApi.CtpTdEvents.OnRspOrderInsert += this.OnRspOrderInsert;                //报单录入请求响应
            tdApi.CtpTdEvents.OnRspOrderAction += this.OnRspOrderAction;                //报单操作请求响应

            tdApi.CtpTdEvents.OnErrRtnOrderInsert += this.OnErrRtnOrderInsert;          //报单录入错误回报
            tdApi.CtpTdEvents.OnErrRtnOrderAction += this.OnErrRtnOrderAction;          //报单操作错误回报

            tdApi.CtpTdEvents.OnRtnOrder += this.OnRtnOrder;                            //报单通知
            tdApi.CtpTdEvents.OnRtnTrade += this.OnRtnTrade;                            //成交通知
            tdApi.CtpTdEvents.OnRtnTradingNotice += this.OnRtnTradingNotice;            //交易通知

            tdApi.CtpTdEvents.OnRspQryInvestor += this.OnRspQryInvestor;                                            //请求查询投资者响应
            tdApi.CtpTdEvents.OnRspQryInvestorPosition += this.OnRspQryInvestorPosition;                            //请求查询投资者持仓响应
            tdApi.CtpTdEvents.OnRspQryInvestorPositionDetail += this.OnRspQryInvestorPositionDetail;                //请求查询投资者持仓明细响应
            tdApi.CtpTdEvents.OnRspQryInvestorPositionCombineDetail += this.OnRspQryInvestorPositionCombineDetail;  //请求查询投资者组合持仓明细响应

            tdApi.CtpTdEvents.OnRspQryTradingAccount += this.OnRspQryTradingAccount;    //请求查询资金账户响应

            tdApi.CtpTdEvents.OnRspQryInstrument += this.OnRspQryInstrument;            //请求查询合约响应
            tdApi.CtpTdEvents.OnRspQryDepthMarketData += this.OnRspQryDepthMarketData;  //请求查询行情响应

            tdApi.CtpTdEvents.OnRspQrySettlementInfoConfirm += this.OnRspQrySettlementInfoConfirm;  //请求查询结算信息确认响应
            tdApi.CtpTdEvents.OnRspQrySettlementInfo += this.OnRspQrySettlementInfo;                //请求查询投资者结算结果响应

            tdApi.CtpTdEvents.OnRspSettlementInfoConfirm += this.OnRspSettlementInfoConfirm;    //确认投资者结算结果响应

            tdApi.SubscribePrivateTopic(1);
            tdApi.SubscribePublicTopic(1);

            tdApi.Init();
            tdApi.Join();
        }

        //错误应答
        void OnRspError(CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspError", pRspInfo);
        }

        //连接请求响应
        void OnFrontConnected()
        {
            DebugAction("OnFrontConnected");

            CThostFtdcReqUserLoginField loginField = new CThostFtdcReqUserLoginField();

            loginField.BrokerID = "4030";
            loginField.UserID = "80002863";
            loginField.Password = "888888";

            tdApi.ReqUserLogin(loginField, requestID++);
        }

        //用户登录请求响应
        void OnRspUserLogin(CThostFtdcRspUserLoginField rspUserLoginfield, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspUserLogin", pRspInfo);

            UserFun(rspUserLoginfield);
        }
        

        //报单通知 
        void OnRtnOrder(CThostFtdcOrderField pOrder)
        {
            DebugAction("OnRtnOrder");

            Console.WriteLine(pOrder.OrderStatus);
            Console.WriteLine(pOrder.OrderSubmitStatus);
        }
        
        //成交通知
        void OnRtnTrade(CThostFtdcTradeField pTrade)
        {
            DebugAction("OnRtnTrade");
        }
        
        //交易通知
        void OnRtnTradingNotice(CThostFtdcTradingNoticeInfoField pTradingNoticeInfo)
        {
            DebugAction("OnRtnTradingNotice");
        }


        //报单录入请求响应
        void OnRspOrderInsert(CThostFtdcInputOrderField pInputOrder, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspOrderInsert", pRspInfo);
        }

        //报单操作请求响应
        void OnRspOrderAction(CThostFtdcInputOrderActionField pInputOrderAction, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspOrderAction", pRspInfo);
        }

        //报单录入错误回报
        void OnErrRtnOrderInsert(CThostFtdcInputOrderField pInputOrder, CThostFtdcRspInfoField pRspInfo)
        {
            DebugAction("OnErrRtnOrderInsert", pRspInfo);
        }

        //报单操作错误回报
        void OnErrRtnOrderAction(CThostFtdcOrderActionField pOrderAction, CThostFtdcRspInfoField pRspInfo)
        {
            DebugAction("OnErrRtnOrderAction", pRspInfo);
        }

        
        //请求查询合约响应
        void OnRspQryInstrument(CThostFtdcInstrumentField pInstrument, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspQryInstrument", pRspInfo);

            if (pInstrument != null)
            {
                System.Console.WriteLine(pInstrument.InstrumentID);
                System.Console.WriteLine(pInstrument.InstrumentName);
                System.Console.WriteLine(pInstrument.ExchangeInstID);
            }
        }

        //请求查询资金账户响应
        void OnRspQryTradingAccount(CThostFtdcTradingAccountField pTradingAccount, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspQryTradingAccount", pRspInfo);

            System.Console.WriteLine(pTradingAccount.Available.ToString());
        }

        
        //查询结算信息响应
        void OnRspQrySettlementInfo(CThostFtdcSettlementInfoField pSettlementInfo, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspQrySettlementInfo", pRspInfo);

            if (pSettlementInfo != null)
            {
                Console.WriteLine(pSettlementInfo.Content);
            }
        }

        //查询投资者结算确认结果响应
        void OnRspQrySettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField pSettlementInfoConfirm, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspQrySettlementInfoConfirm", pRspInfo);

            //如果结果为空则说明没有确认过结果
            if (bIsLast && pSettlementInfoConfirm == null)
            {
                this.ReqSettlementConfirmInfo();
            }
        }

        //确认投资者结算结果响应
        void OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField pSettlementInfoConfirm, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspSettlementInfoConfirm", pRspInfo);

            if (bIsLast && pSettlementInfoConfirm != null)
            {
                Console.WriteLine(pSettlementInfoConfirm.ConfirmTime);
            }
        }


        //请求查询投资者响应
        void OnRspQryInvestor(CThostFtdcInvestorField pInvestor, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspQryInvestor", pRspInfo);

            DisplayFieldInfo(pInvestor);
        }

        //请求查询投资者持仓响应
        void OnRspQryInvestorPosition(CThostFtdcInvestorPositionField pInvestorPosition, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspQryInvestorPosition", pRspInfo);

            DisplayFieldInfo(pInvestorPosition);
        }

        //请求查询投资者持仓明细响应
        void OnRspQryInvestorPositionDetail(CThostFtdcInvestorPositionDetailField pInvestorPositionDetail, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspQryInvestorPositionDetail", pRspInfo);
        }

        //请求查询投资者组合持仓明细响应
        void OnRspQryInvestorPositionCombineDetail(CThostFtdcInvestorPositionCombineDetailField pInvestorPositionCombineDetail, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            DebugAction("OnRspQryInvestorPositionCombineDetail", pRspInfo);
        }

        
        //请求查询行情响应
        void OnRspQryDepthMarketData(CThostFtdcDepthMarketDataField pDepthMarketData, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            marketData = pDepthMarketData;
        }
    }
    
}
